<template>
  <div>
    <van-nav-bar title="搜索中心" left-arrow @click-left="$router.back()"></van-nav-bar>
    <van-search
      v-model.trim="keyword"
      show-action
      placeholder="请输入搜索关键词"
      @input="hGetSuggestion_with_throttle">
      <!-- 我们使用插件节流的方式实现 -->
      <template #action>
        <div @click="hSearch">搜索</div>
      </template>
    </van-search>
    <!-- 2.搜索建议 -->
    <van-cell-group v-if="keyword">
        <van-cell
          v-for="(item,idx)  in cSuggestion"
          :key="idx"
          @click="hSearchSuggestion(idx)"
          icon="search">
          <div v-html="item"></div>
        </van-cell>
    </van-cell-group>
    <!-- 3.历史记录 -->
    <van-cell-group v-else>
        <van-cell title="历史记录"></van-cell>
        <van-cell
          v-for="(item, idx) in history"
          :key="idx"
          :title="item"
          @click="$router.push('/search/result?keyword=' + item)">
          <!-- @click.stop 为了阻止冒泡 -->
            <van-icon name="close"  @click.stop="hDeleteHistory(idx)"></van-icon>
        </van-cell>
    </van-cell-group>
  </div>
</template>

<script>
import { getSuggestion } from '@/api/search'
import { setItem, getItem } from '@/utils/storage'
// 代码优化2-防抖和节流--降频
import _ from 'lodash'
// 定义一个常量，保存key
// 代码优化1-消除魔法字符串
const SEARCH_HISTORY_KEY = 'searchHistory'
export default {
  name: 'search',
  data () {
    return {
      keyword: '',
      // 搜索建议
      suggestion: [],
      // 保存历史记录  ['正则', 'javascript']
      // 初始化，先从本地存储中取值，取不到，则用[]
      history: getItem(SEARCH_HISTORY_KEY) || []
    }
  },
  computed: {
    // 计算属性对suggestion中保存的内容做高亮显示
    cSuggestion () {
      // 全局正则匹配关键词
      const reg = new RegExp(this.keyword, 'gi')
      // 对suggeston中的每一项 进行正则替换,得到具备高亮的字符串
      const arr = this.suggestion.map(str => {
        return str.replace(reg, function (s) {
          return `<span style="color:red">${s}</span>`
        })
      })
      return arr
    }
  },
  methods: {
    // 添加到历史记录
    addHistory (str) {
      const idx = this.history.findIndex(item => item === str)
      if (idx !== -1) {
        // 有重复项,删除它
        this.history.splice(idx, 1)
      }
      // 在数组的头部去添加
      this.history.unshift(str)
      // 做持久化
      setItem(SEARCH_HISTORY_KEY, this.history)
    },
    // 搜索的第一种方法: 用户在搜索建议上点击了
    hSearchSuggestion (idx) {
      console.log(idx)
      const keyword = this.suggestion[idx]
      // 1.把当前的搜索建议 添加到搜索记录中去
      this.addHistory(keyword)
      // 2.todo 跳转到搜索结果页
      this.$router.push({
        path: 'search/result',
        query: {
          keyword
        }
      })
    },
    // 搜索的第二种方法 : 用户点击搜索按钮
    hSearch () {
      if (this.keyword === '') {
        return
      }
      // 1.把当前搜索内容 添加到搜索记录中

      this.addHistory(this.keyword)
      // 2.todo 跳转到搜索结果页
      this.$router.push({
        path: 'search/result',
        query: {
          keyword: this.keyword
        }
      })
    },
    // 用户点击删除历史记录
    hDeleteHistory (idx) {
      this.history.splice(idx, 1)
    },
    // 当用户搜索框发生变化时就触发
    async hGetSuggestion () {
      console.log(this.keyword)
      // 搜索框发生变化-显示对应搜索建议
      if (this.keyword === '') {
        this.suggestion = []
        return
      }
      // 1.调接口, 获取关键词搜索的建议
      const result = await getSuggestion(this.keyword)
      console.log(result);
      // 渲染在列表suggestion
      this.suggestion = result.data.data.options
    },
    // 插件-防抖
    hGetSuggestion_with_debounce: _.debounce(function () {
      console.log(this.keyword)
      this.hGetSuggestion()
    }, 500),
    // 插件-节流
    hGetSuggestion_with_throttle: _.throttle(function () {
      console.log(this.keyword)
      this.hGetSuggestion()
    }, 500),

    // 当用户输入内容变化时，就会执行 --- 防抖处理
    // 防抖（10秒）: 目标就是降频。一件事如果执行的频率非常快，抖动：没有意义的， 不要让你抖...
    //    思路：
    //      当这个函数被调用时，不是立即执行的时，而是延迟 10 秒再执行.
    //      如果在10秒之内，再次调用这个函数，则从当前被调用的时间开始算，再延迟 10 秒(10秒内不能再次调用函数，
    //       一旦打断，就要重新计时)。
    //       如果10秒内没有再次调用这个函数，则10秒达了之后，执行代码。
    // 生活中： 等电梯
    // 游戏中： 英雄回城

    hGetSuggestion_with_fang_dou () {
      console.log('当前用户的输入', this.keyword)
      // 以防抖5s为例： (值越大，越不灵敏)
      // 用户第一次输入第一个字符，代码不会立即去执行（ajax不是立即发出去）
      // 再是等5s之后再发ajax.如果在这5s内，用户输入第二个字符，再向后再延迟5s.

      if (this.timer) {
        clearTimeout(this.timer)
      }
      this.timer = setTimeout(() => {
        this.hGetSuggestion()
      }, 5 * 1000)
    },

    // 当用户输入内容变化时，就会执行 --- 节流处理
    // 节流（10秒）: 目标就是降频。一件事如果执行的频率非常快，节流就是把频率降至指定的值
    //    思路：
    //      当这个函数被调用时，不是立即执行的时，而是检查本次执行距离上一次执行中间是否相隔10秒。
    //      如果相隔时间不足10s，则不执行；否则就执行
    // 生活中： 你女朋友每小时都要你发定位；节流处理（5小时）：如果早上8点发了定位，则下一次发定位时
    //         时间是：下午1点。中间其它时间不发定位

    // 游戏中： 射击游戏，点一次鼠标发一颗子弹，你是否可能按下鼠标不放，就不间断发子弹？

    hGetSuggestion_with_jie_liu () {
      console.log('当前用户的输入', this.keyword, (new Date()).toLocaleTimeString())
      // 以节流3s为例： (值越大，越不灵敏)
      // 对于本次调用，检查本次执行距离上一次执行中间是否相隔5秒
      // 是：执行，否：不执行

      if (this.timer) {
        return
      }
      this.timer = setTimeout(() => {
        this.timer = null
        this.hGetSuggestion()
      }, 100) //  3 * 1000
    }
  }
}
</script>

<style>

</style>
